package com.hui.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hui.dto.*;
import com.hui.entity.Assets;
import com.hui.entity.AssetsBorrow;
import com.hui.exception.IllegalParamException;
import com.hui.exception.ServerErrorException;
import com.hui.exception.VersionException;
import com.hui.mapper.AssetsBorrowMapper;
import com.hui.mapper.AssetsMapper;
import com.hui.service.AssetsBorrowService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
@CacheConfig(cacheNames = "assetsBorrow")
public class AssetsBorrowServiceImpl implements AssetsBorrowService {

    @Autowired
    private AssetsBorrowMapper assetsBorrowMapper;
    @Autowired
    private AssetsMapper assetsMapper;

    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true)
    @Override
    public int insert(AssetsBorrowInsertDTO dto) {
        String info = dto.getInfo();
        Long fkAssetsId = dto.getFkAssetsId();
        Integer count = dto.getCount();
        //判断申请时间和预计归还时间
        if (dto.getBorrowTime().isAfter(dto.getExpectedReturnTime())) {
            throw new IllegalParamException("申请时间不能晚于预计归还时间");
        }
        //查询资产信息
        Assets assets = assetsMapper.select(fkAssetsId);
        if (ObjectUtil.isNull(assets)) {
            throw new ServerErrorException("资产不存在");
        }
        //判断剩余库存是否充足
        Integer stock = assets.getStock();
        String stockUnit = assets.getStockUnit();
        if (count > stock) {
            throw new IllegalParamException("库存不足，仅剩" + stock + stockUnit);
        }
        //拷贝属性
        AssetsBorrow assetsBorrow = BeanUtil.copyProperties(dto, AssetsBorrow.class);
        //设置默认值
        assetsBorrow.setInfo(StrUtil.isBlank(info) ? "暂无描述" : info);
        assetsBorrow.setVersion(0L);
        assetsBorrow.setDeleted(0);
        assetsBorrow.setCreated(LocalDateTime.now());
        assetsBorrow.setUpdated(LocalDateTime.now());
        //DB添加：添加申请记录
        int insertResult = assetsBorrowMapper.insert(assetsBorrow);
        if (insertResult <= 0) {
            throw new ServerErrorException("DB添加失败");
        }
            //DB修改：扣减库存
            stock -= count;
            assets.setStock(stock);
                int updateResult = assetsMapper.update(assets);
                if (updateResult <= 0) {
                    throw new ServerErrorException("DB修改失败");
                }
                return insertResult + updateResult;
            }

    @Cacheable(key = "#p0",condition = "#p0 !=null", unless = "#result == null")
    @Override
    public AssetsBorrow select(Long id) {
        AssetsBorrow result = assetsBorrowMapper.select(id);
        if (ObjectUtil.isNull(result)){
            throw new ServerErrorException("资产不存在");
        }
        return result;
    }

    @Cacheable(key = "#root.methodName", unless = "#result == null")
    @Override
    public List<AssetsBorrow> list() {
        AssetsBorrowPageDTO dto = new AssetsBorrowPageDTO();
        return assetsBorrowMapper.list(dto);
    }

    @Cacheable(key = "#root.methodName+ ':' + #p0.toString() + ':' + #p0.getPageSize()", condition = "#p0 != null")
    @Override
    public PageInfo<AssetsBorrow> page(AssetsBorrowPageDTO dto) {
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        return new PageInfo<>(assetsBorrowMapper.list(dto));
    }

    @CacheEvict(allEntries = true)
    @Transactional
    @Override
    @Retryable(value = VersionException.class)
    public int update(AssetsBorrowUpdateDTO dto) {
        Long id = dto.getId();
        if (ObjectUtil.isNull(id)){
            throw new IllegalParamException("ID为空");
        }
        AssetsBorrow assetsBorrow = assetsBorrowMapper.select(id);
        if (ObjectUtil.isNull(assetsBorrow)){
            throw new ServerErrorException("记录不存在");
        }
        BeanUtil.copyProperties(dto, assetsBorrow);
        assetsBorrow.setUpdated(LocalDateTime.now());
        int result = assetsBorrowMapper.update(assetsBorrow);
        if (result <= 0){
            throw new VersionException("DB修改失败");
        }
        return result;
    }

    @CacheEvict(allEntries = true)
    @Override
    public int delete(Long id) {
        int result = assetsBorrowMapper.delete(id);
        if (result <= 0){
            throw new ServerErrorException("DB删除失败");
        }
        return result;
    }

    @CacheEvict(allEntries = true)
    @Override
    public int deleteBatch(List<Long> ids) {
        int result = assetsBorrowMapper.deleteBatch(ids);
        if (result <= 0){
            throw new ServerErrorException("DB删除失败");
        }
        return result;
    }


}
